//
//  rovbus.h
//  YHROV-ARM_UnitTest
//
//  Created by CmST0us on 16/11/1.
//  Copyright © 2016年 广州睿航电子科技有限公司. All rights reserved.
//

#ifndef rovbus_h
#define rovbus_h

#include <stdio.h>
/**
 @brief rovbus 协议结构体
 */
typedef struct{
    unsigned char     _start;       //起始 ":"
    unsigned char     _address[2];  //地址
    unsigned char     _function[2]; //操作
    unsigned char     *_data;       //数据
    int               _data_count;  //数据长度（转换前），注意rovbus将每一个字节的16进制分成2个字符，例如数据 0xFA 就被转为 "FA"
    unsigned char     _lrc[2];      //LRC校验
    unsigned char     _end[2];      //结束 "\r\n"
}rovbus_t;


typedef rovbus_t* rovbus_ref_t;

typedef char* rovbus_address_t;

typedef char* rovbus_fuction_t;

/**
 @brief 创建一个rovbus实例
 @return rovbus实例的指针，注意使用完之后需要释放
 @see rovbus_free()
 */
rovbus_ref_t rovbus_new();
/**
 @brief 释放rovbus实例， 同时释放r->_data
 @param r 指向rovbus实例的指针
 @see rovbus_set_data()
 */
void rovbus_free(rovbus_ref_t r);

/**
 @brief 设置rovbus实例的 地址 参数
 @param r 指向rovbus实例的指针
 @param addr 地址 字符串，两个字符。每个字符范围是 '0' ~ '9' || 'a' ~ 'f' || 'A' ~ 'F'
 */
void rovbus_set_address(rovbus_ref_t r, rovbus_address_t addr);
/**
 @brief 设置rovbus实例的 操作 参数
 @param r 指向rovbus实例的指针
 @param addr 操作 字符串，两个字符。每个字符范围是 '0' ~ '9' || 'a' ~ 'f' || 'A' ~ 'F'
 */
void rovbus_set_fuction(rovbus_ref_t r, rovbus_fuction_t function);
//数据为深拷贝
/**
 @brief 设置rovbus实例的 数据 参数，计算出长度赋值给 r->_data_cont。 
        注意数据buffer将被拷贝至新的堆内存，所以如果buffer为堆内存，函数返回后可释放 buffer
 @param r 指向rovbus实例的指针
 @param buffer 指向数据的指针
 @param len 数据的长度
 @return -1 失败
         0  成功
 */
int rovbus_set_data(rovbus_ref_t r,const void* buffer, int len);
/**
 @brief 计算rovbus实例的LRC,赋值给 r->_lrc
 @param r 指向rovbus实例的指针
 */
void rovbus_compute_lrc(rovbus_ref_t r);
/**
 @brief 通过符合rovbus协议字符串创建rovbus实例
 @param string 通过符合rovbus协议字符串
 @param len    字符串长度，长度应大于9，如果输入小于9，返回NULL
 @return rovbus实例， 实例在使用完后需要释放
 @see rovbus_free()
 */
rovbus_ref_t rovbus_init_with_string(const void* string, int len);

/**
 @brief 检查rovbus实例是否合法
 @param r 指向rovbus实例的指针
 @return  0 合法
         -1 非法
 */
int rovbus_check_legal(const rovbus_ref_t r);
/**
 @brief 校验rovbus实例的LRC
 @param r 指向rovbus实例的指针
 @return  0 合法
         -1 非法
 */
int rovbus_check_lrc(const rovbus_ref_t r);
/**
 @brief 取回rovbus实例中的数据
 @param buffer 数据缓冲区
 @param len    缓冲区长度
 @return -1 失败
         >0  取回的数据长度
 */
int rovbus_get_data(rovbus_ref_t r, void* buffer, int len);

/**
 @brief 将rovbus实例输出为字符串
 @param buffer 数据缓冲区
 @param len    缓冲区长度
 @return -1 失败
         >0  取回的数据长度
 */
int rovbus_get_protocol_string(const rovbus_ref_t r, void *buffer, int len);

/**
 @brief 取回操作地址
 @param r 指向rovbus实例的指针
 @param i
            0代表高4位ASCII字符
            1代表低4位ASCII字符
 @discuss 例如 "AD" 高四位ASCII字符为A,低四位ASCII字符为D
 @return -1 失败
        char 操作地址字符
 */
char rovbus_get_address(const rovbus_ref_t r, int i);
/**
 @brief 取回操作函数
 @param r 指向rovbus实例的指针
 @param i
            0代表高4位ASCII字符
            1代表低4位ASCII字符
 @discuss 例如 "AD" 高四位ASCII字符为A,低四位ASCII字符为D
 @return -1 失败
        char 操作函数字符
 */
char rovbus_get_function(const rovbus_ref_t r, int i);
/**
 @brief 取回操作地址并转为数
 @param r 指向rovbus实例的指针
 @return -1 失败
        unsigned 操作地址数
 */
unsigned int rovbus_get_address_num(const rovbus_ref_t r);
/**
 @brief 取回操作函数并转为数
 @param r 指向rovbus实例的指针
 @return -1 失败
         unsigned int 操作函数数
 */
unsigned int rovbus_get_function_num(const rovbus_ref_t r);

#endif /* rovbus_h */
